<!DOCTYPE html>
<html>
<head>
<title>RTCRtpSender.getParameters</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
promise_test(async t => {
  let pc1 = new RTCPeerConnection();
  t.add_cleanup(() => pc1.close());
  let pc2 = new RTCPeerConnection();
  t.add_cleanup(() => pc2.close());
  let video_sender, audio_sender;

  return createStreams({audio:true, video:true}, 1)
    .then(function(streams) {
      video_sender = pc1.addTrack(streams[0].getVideoTracks()[0], streams[0]);
      audio_sender = pc1.addTrack(streams[0].getAudioTracks()[0], streams[0]);
    }).then(() => connect_pcs(pc1, pc2))
    .then(() => {
      video_parameters = video_sender.getParameters();
      verifySenderParameters(video_parameters, 'video');

      audio_parameters = audio_sender.getParameters();
      verifySenderParameters(audio_parameters, 'audio');
    });
}, 'getParameters()');

/**
 * Helper functions to tests.
 */

function createStreams(constraints, numStreams, streamsSoFar = []) {
  if (numStreams == 0) {
    return Promise.resolve(streamsSoFar);
  }
  return navigator.mediaDevices.getUserMedia(constraints)
    .then(function(stream) {
      return createStreams(constraints,
                           numStreams - 1,
                           streamsSoFar.concat([stream]));
    });
}

function connect_pcs(localPc, remotePc) {
  return localPc.createOffer()
  .then(offer => Promise.all([
    localPc.setLocalDescription(offer),
    remotePc.setRemoteDescription(offer)]))
  .then(() => remotePc.createAnswer())
  .then(answer => Promise.all([
    remotePc.setLocalDescription(answer),
    localPc.setRemoteDescription(answer)]))
}

function verifySenderParameters(parameters, kind) {
  assert_own_property(parameters, "transactionId", "transactionId");
  assert_own_property(parameters, "rtcp", "rtcp");

  assert_greater_than(parameters.codecs.length, 0);
  for(let codec of parameters.codecs) {
    if(kind === 'video') {
      assert_false(codec.hasOwnProperty("channels"), "no channels on video tracks");
      assert_equals(codec.clockRate, 90000);
    } else {
      assert_own_property(codec, "channels", "channel count");
      assert_greater_than(codec.clockRate, 0);
    }

    assert_own_property(codec, "mimeType", "mime type");
    assert_true(codec.mimeType.startsWith(kind + "/"));

    assert_own_property(codec, "payloadType", "payload type");
  }

  assert_own_property(parameters, "headerExtensions", "headerExtension");
  for(let header of parameters.headerExtensions) {
    assert_own_property(header, "uri");
    assert_own_property(header, "id");
  }

  assert_greater_than(parameters.encodings.length, 0);
  for(let encoding of parameters.encodings) {
    assert_false(encoding.hasOwnProperty("codecPayloadType"), "unset codecPayloadType");
    assert_not_own_property(encoding, "rid");
    assert_true(encoding.active);
    assert_equals(encoding.priority, "low");
    assert_false(encoding.hasOwnProperty("maxBitrate"), "unset maxBitrate");
    assert_false(encoding.hasOwnProperty("maxFramerate"), "unset maxFramerate");
    assert_false(encoding.hasOwnProperty("scaleResolutionDownBy"), "unset scaleResolutionDownBy");
  }

  assert_false(parameters.hasOwnProperty("degradationPreference"), "unimplemented degradationPreference");
}
</script>
</body>
</html>
